using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Text;

using Yaml.Library;

namespace Yaml.Grammar
{
	public partial class YamlParser
	{
		private int _position;

		public int Position
		{
			get { return _position; }
			set { _position = value; }
		}

		private IParserInput<Char> _input;

		private Collection<Pair<int, string>> _errors = new Collection<Pair<int, string>>();
		
		public Collection<Pair<int, string>> Errors {
			get {
				return this._errors;
			}
		}

		public YamlParser() { }

		private void SetInput(IParserInput<Char> input)
		{
			_input = input;
			_position = 0;
		}

		/*        private bool TerminalMatch(char ch)
        {
            if (_input.HasInput(_position))
            {
                Char symbol = _input.GetInputSymbol(_position);
                return ch == symbol;
            }
            return false;
        }*/

		private bool TerminalMatch(char ch, int pos)
		{
			if (_input.HasInput(pos))
			{
				Char symbol = _input.GetInputSymbol(pos);
				return ch == symbol;
			}
			return false;
		}

		private char MatchTerminal(char ch, out bool success)
		{
			success = false;
			if (_input.HasInput(_position))
			{
				Char symbol = _input.GetInputSymbol(_position);
				if (ch == symbol)
				{
					_position++;
					success = true;
				}
				return symbol;
			}
			return default(Char);
		}

		private char MatchTerminalRange(char start, char end, out bool success)
		{
			success = false;
			if (_input.HasInput(_position))
			{
				Char symbol = _input.GetInputSymbol(_position);
				if (start <= symbol && symbol <= end)
				{
					_position++;
					success = true;
				}
				return symbol;
			}
			return default(Char);
		}

		private char MatchTerminalSet(string terminalSet, bool isComplement, out bool success)
		{
			success = false;
			if (_input.HasInput(_position))
			{
				Char symbol = _input.GetInputSymbol(_position);
				bool match = isComplement ? terminalSet.IndexOf(symbol) == -1 : terminalSet.IndexOf(symbol) > -1;
				if (match)
				{
					_position++;
					success = true;
				}
				return symbol;
			}
			return default(Char);
		}

		private string MatchTerminalString(string terminalString, out bool success)
		{
			int current_position = _position;
			foreach (char ch in terminalString)
			{
				MatchTerminal(ch, out success);
				if (!success)
				{
					_position = current_position;
					return null;
				}
			}
			success = true;
			return terminalString;
		}

		private void Error(string message)
		{
			Errors.Add(new Pair<int, string>(_position, message));
		}

		private void ClearError()
		{
			Errors.Clear();
		}

		public string ErrorMessages
		{
			get {
				StringBuilder text = new StringBuilder();
				foreach (Pair<int, string> msg in Errors)
				{
					text.Append(_input.FormatErrorMessage(msg.Left, msg.Right));
					text.AppendLine();
				}
				return text.ToString();
			}
		}
	}
}
